home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Topik / Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].zip / Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].adf / MicroRayDbw / support.c < prev    next >
C/C++ Source or Header  |  1988-12-11  |  10KB  |  368 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1988, David B. Wecker            *
  4.  *                All Rights Reserved                *
  5.  *                                    *
  6.  * This file is part of DBW_uRAY                    *
  7.  *                                    *
  8.  * DBW_uRAY is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts        *
  10.  * responsibility to anyone for the consequences of using it or for    *
  11.  * whether it serves any particular purpose or works at all, unless    *
  12.  * he says so in writing. Refer to the DBW_uRAY General Public        *
  13.  * License for full details.                        *
  14.  *                                    *
  15.  * Everyone is granted permission to copy, modify and redistribute    *
  16.  * DBW_uRAY, but only under the conditions described in the        *
  17.  * DBW_uRAY General Public License. A copy of this license is        *
  18.  * supposed to have been given to you along with DBW_uRAY so you    *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this    *
  21.  * notice must be preserved on all copies.                *
  22.  ************************************************************************
  23.  *                                    *
  24.  * Authors:                                *
  25.  *    DBW - David B. Wecker                        *
  26.  *                                    *
  27.  * Versions:                                *
  28.  *    V1.0 881023 DBW    - First released version            *
  29.  *    V1.1 881110 DBW - Fixed scan coherence code            *
  30.  *    V1.2 881125 DBW - Removed ALL scan coherence code (useless)    *
  31.  *              added "fat" extent boxes            *
  32.  *                                    *
  33.  ************************************************************************/
  34.  
  35. #include "uray.h"
  36.  
  37. /************************************************************************/
  38. /********************* support (misc) routines **************************/
  39. /************************************************************************/
  40.  
  41.  
  42. /* leave the program. if msg is not NULL then an error occurred */
  43. /* also, return any used resources at this point */
  44.  
  45. void leave(msg,arg1,arg2)
  46. char    *msg,*arg1,*arg2;
  47.     {
  48.  
  49.     /* are we writing a .tmp file */
  50.     if (bpp && fp) fclose(fp);
  51.  
  52.     /* are we writing a .ilbm file (go back and put in the colortable) */
  53.     if (fp2) {
  54.     fseek(fp2,(long)pos2,0); wfil(fp2,4,&lsize);
  55.     lsize -= BODYsize;
  56.     lsize += FORMsize;
  57.     fseek(fp2,(long)pos1,0); wfil(fp2,4,&lsize);
  58.     fseek(fp2,(long)pos3,0);
  59.     fwrite(colors,1,48,fp2);
  60.     fclose(fp2);
  61.     }
  62.  
  63.     /* is there an error message */
  64.     if (msg) {
  65.     fprintf(stderr,"\nURAY: ");
  66.     fprintf(stderr,msg,arg1,arg2);
  67.     fprintf(stderr,"\n");
  68.     exit(-2);
  69.     }
  70.     exit(1);
  71.     }
  72.  
  73. /* do a malloc and make sure that we got the memory */
  74. char *my_malloc(size)
  75.     {
  76.     char    *result,*malloc();
  77.  
  78.     if (!(result = malloc(size))) leave("Can't malloc memory");
  79.     return result;
  80.     }
  81.  
  82. /* do a calloc and make sure that we got the memory */
  83. char *my_calloc(size,num)
  84.     {
  85.     char    *result,*calloc();
  86.  
  87.     if (!(result = calloc(size,num))) leave("Can't calloc memory");
  88.     return result;
  89.     }
  90.  
  91. /* allocate and initialize a node (for input routine) */
  92. NODE    *doalloc(typ) {
  93.     NODE    *nod;
  94.     EXTENT  *newe;
  95.  
  96.     /* get memory for the new object */
  97.     switch (typ) {
  98.     case TYP_E:    nod = (NODE *)my_malloc(sizeof(EXTENT));    break;
  99.     case TYP_S:    nod = (NODE *)my_malloc(sizeof(SPHERE));    break;
  100.     case TYP_T:    nod = (NODE *)my_malloc(sizeof(TRIANGLE));  break;
  101.     case TYP_Q:    nod = (NODE *)my_malloc(sizeof(QUAD));        break;
  102.     case TYP_R:    nod = (NODE *)my_malloc(sizeof(RING));        break;
  103.     case TYP_L:    nod = (NODE *)my_malloc(sizeof(LIGHT));        break;
  104.     }
  105.  
  106.     if (typ == TYP_L) return;
  107.  
  108.     nod->next    = NULL;
  109.     nod->typ    = typ;
  110.  
  111.     /* if this is an extent, just return it */
  112.     if (typ == TYP_E) {
  113.     extcnt++;
  114.     return nod;
  115.     }
  116.  
  117.     /* else get memory for an extent around the object (and count the obj) */
  118.     newe    = (EXTENT *)doalloc(TYP_E);
  119.     newe->child    = nod;
  120.     objcnt++;
  121.  
  122.     /* and link it in to the extent tree */
  123.     newe->next    = nodes;
  124.     nodes    = (NODE *)newe;
  125.  
  126.     /* return the object to the user */
  127.     return nod;
  128.     }
  129.  
  130. /* add a light to the list of lights (for fast lookup) */
  131. void addlight(nod)
  132. NODE    *nod;
  133.     {
  134.     LIGHT   *l;
  135.  
  136.     if (nod->att->kl == 0.0) return;
  137.  
  138.     l = (LIGHT *)doalloc(TYP_L);
  139.     l->next    = lights;
  140.     l->child    = nod;
  141.     lights    = l;
  142.     }
  143.  
  144. /* debug routine (see DEBUG_dumpnodes in uray.h) for dumping nodes */
  145. void dumpnodes(n,lev)
  146. NODE    *n;
  147.     {
  148.     int        i;
  149.     EXTENT  *e;
  150.  
  151.     /* do each node at this level */
  152.     while (n) {
  153.  
  154.     /* space over the current level amount */
  155.     for (i=0; i<lev; i++) printf(".");
  156.  
  157.     /* print out type of node */
  158.     printf(" %c",TYPstr[n->typ]);
  159.  
  160.     /* if an extent, then go down recursively */
  161.     if (n->typ == TYP_E) {
  162.         e = (EXTENT *)n;
  163.         if (e->child->typ != TYP_E)    printf("%c",TYPstr[e->child->typ]);
  164.         else            printf(" ");
  165.  
  166.         /* print extent range */
  167.         printf(" [%7.4f,%7.4f] [%7.4f,%7.4f] [%7.4f,%7.4f]\n",
  168.         e->min[0],e->max[0],e->min[1],e->max[1],
  169.              e->min[2],e->max[2]);
  170.  
  171.         /* do recursion */
  172.         if (e->child->typ == TYP_E) dumpnodes(e->child,lev+1);
  173.         }
  174.  
  175.     /* get next node at this level */
  176.     n = n->next;
  177.     }
  178.     }
  179.  
  180. /* make vector into unit vector */
  181. void vunit(A,B)
  182. VEC A,B;
  183.     {
  184.     register FLTDBL  tmp;
  185.  
  186.     tmp = 1.0 / vnorm(A);
  187.     vscale(tmp, A, B);
  188.     }
  189.  
  190. /* find the normal to a sphere */
  191. void spherenormal(intersect,s,normal)
  192. VEC    intersect,normal;
  193. SPHERE    *s;
  194.     {
  195.     VEC    v1;
  196.  
  197.     /* get the direction from the center */
  198.     vcomb(-1.0, intersect, s->cen, v1);
  199.  
  200.     /* then normalize */
  201.     vunit(v1,normal);
  202.     }    
  203.  
  204. /* find the normal to a plane */
  205. void planenormal(s,normal)
  206. QUAD    *s;
  207. VEC    normal;
  208.     {
  209.     VEC    v1;
  210.  
  211.     /* first do vector cross product */
  212.     vcross(s->v1,s->v2,v1);
  213.  
  214.     /* then normalize */
  215.     vunit(v1,normal);
  216.     }
  217.  
  218. /* read the input .dat file  */
  219. void readinput()
  220.     {
  221.     int        i,j;
  222.     FLTDBL    val;
  223.     int        tmp1,tmp2;
  224.  
  225.     /* get the input file open */
  226.     printf("Creating objects\n");
  227.     sprintf(str,"%s.dat",basnam);
  228.     fp = fopen(str,"r");
  229.     if (!fp) leave("Bad input file");
  230.  
  231.     /* read each line of the file */
  232.     while (fgets(str,80,fp)) {
  233.  
  234.     /* every legal (~comment) line must start with a string and a num */
  235.     if (sscanf(str,SCAN1,cmd,&val) != 2) continue;
  236.  
  237.     /* read in the global parameters */
  238.     if (!strcmp(cmd,"DEPTH"))    depth        = (int)val;
  239.     else if (!strcmp(cmd,"ROWS"))    rows        = (short)val;
  240.     else if (!strcmp(cmd,"START"))    startrow    = (short)val;
  241.     else if (!strcmp(cmd,"END"))    endrow        = (short)val;
  242.     else if (!strcmp(cmd,"COLS"))    cols        = (short)val;
  243.     else if (!strcmp(cmd,"BPP"))    bpp        = (short)val;
  244.     else if (!strcmp(cmd,"AOV"))    aov        = (int)val;
  245.     else if (!strcmp(cmd,"ASPECT"))    aspect        = val;
  246.     else if (!strcmp(cmd,"NEAR"))
  247.         sscanf(str,SCAN2,cmd,&NEAR[0],&NEAR[1],&NEAR[2]);
  248.     else if (!strcmp(cmd,"FAR"))
  249.         sscanf(str,SCAN2,cmd,&FAR[0],&FAR[1],&FAR[2]);
  250.     else if (!strcmp(cmd,"GROUND"))
  251.         sscanf(str,SCAN2,cmd,&GROUND[0],&GROUND[1],&GROUND[2]);
  252.     else if (!strcmp(cmd,"BASE"))    base        = val;
  253.  
  254.     /* read in attributes */
  255.     else if (!strcmp(cmd,"ATTRIBUTES")) {
  256.         natts   = (int)val;
  257.         atts    = (ATT *)my_calloc(sizeof(ATT),natts);
  258.  
  259.         /* read in each attribute line */
  260.         for (i=0; i<natts; i++) {
  261.         fgets(str,80,fp);
  262.         if (sscanf(str,SCAN3,
  263.             &atts[i].color[0],&atts[i].color[1],&atts[i].color[2],
  264.             &atts[i].kd,&atts[i].ks,&atts[i].kt,&atts[i].ir,
  265.             &atts[i].kl,&atts[i].dist,&atts[i].kf,
  266.             &tmp1,&tmp2,
  267.             &atts[i].p1[0],&atts[i].p1[1],&atts[i].p1[2],
  268.             &atts[i].p2[0],&atts[i].p2[1],&atts[i].p2[2])
  269.             < 12
  270.             ) leave("Bad attribute");
  271.         atts[i].wave = (short)tmp1;
  272.         atts[i].tex  = (short)tmp2;
  273.         }
  274.         }
  275.  
  276.     /* read in waves */
  277.     else if (!strcmp(cmd,"WAVES")) {
  278.         nwaves  = (int)val;
  279.         waves   = (WAVE *)my_calloc(sizeof(WAVE),nwaves);
  280.  
  281.         /* read in each wave line */
  282.         for (i=0; i<nwaves; i++) {
  283.         fgets(str,80,fp);
  284.         if (sscanf(str,SCAN4,
  285.             &waves[i].cen[0],&waves[i].cen[1],&waves[i].cen[2],
  286.             &waves[i].amp,&waves[i].phase,&waves[i].length,
  287.             &waves[i].damp)
  288.             < 7) leave("Bad wave");
  289.         }
  290.         }
  291.  
  292.     /* read in an object - SPHERE */
  293.     else if (!strcmp(cmd,"SPHERE")) {
  294.         sph        = (SPHERE *)doalloc(TYP_S);
  295.         sscanf(str,SCAN5,cmd,&j,
  296.         &sph->cen[0],&sph->cen[1],&sph->cen[2],
  297.         &sph->rad);
  298.         sph->rad *= sph->rad;
  299.         sph->att  = &atts[j];
  300.         if (sph->rad < TOL) sph->rad = TOL;
  301.         addlight(sph);
  302.         }
  303.  
  304.     /* read in an object - QUAD */
  305.     else if (!strcmp(cmd,"QUAD")) {
  306.         qua        = (QUAD *)doalloc(TYP_Q);
  307.         sscanf(str,SCAN6,cmd,&j,
  308.         &qua->p0[0],&qua->p0[1],&qua->p0[2],
  309.         &qua->v1[0],&qua->v1[1],&qua->v1[2],
  310.         &qua->v2[0],&qua->v2[1],&qua->v2[2]);
  311.         qua->att = &atts[j];
  312.         addlight(qua);
  313.         }
  314.  
  315.     /* read in an object - TRIANGLE */
  316.     else if (!strcmp(cmd,"TRIANGLE")) {
  317.         tri        = (TRIANGLE *)doalloc(TYP_T);
  318.         sscanf(str,SCAN6,cmd,&j,
  319.         &tri->p0[0],&tri->p0[1],&tri->p0[2],
  320.         &tri->v1[0],&tri->v1[1],&tri->v1[2],
  321.         &tri->v2[0],&tri->v2[1],&tri->v2[2]);
  322.         tri->att = &atts[j];
  323.         addlight(tri);
  324.         }
  325.  
  326.     /* read in an object - RING */
  327.     else if (!strcmp(cmd,"RING")) {
  328.         rin        = (RING *)doalloc(TYP_R);
  329.         sscanf(str,SCAN7,cmd,&j,
  330.         &rin->p0[0],&rin->p0[1],&rin->p0[2],
  331.         &rin->v1[0],&rin->v1[1],&rin->v1[2],
  332.         &rin->v2[0],&rin->v2[1],&rin->v2[2],
  333.         &rin->rad1,&rin->rad2);
  334.         rin->rad1 *= rin->rad1;
  335.         rin->rad2 *= rin->rad2;
  336.         rin->att = &atts[j];
  337.         vunit(rin->v1,rin->v1);
  338.         vunit(rin->v2,rin->v2);
  339.         addlight(rin);
  340.         }
  341.     }
  342.  
  343.     /* fix up global parameters */
  344.     if (endrow > rows)        endrow   = rows;
  345.     if (startrow >= endrow) startrow = endrow - 1;
  346.     if (startrow < 0)        startrow = 0;
  347.     cols &= 0xFFF8;
  348.  
  349.     /* print out what we read in (sanity check) */
  350.     printf("\n");
  351.     printf("    Input file name: %14s\n",basnam);
  352.     printf("    Maximum recursion depth: %6d\n",depth);
  353.     printf("    Dimensions:              %6d rows (%d,%d)  %d columns\n",
  354.     rows,startrow,endrow,cols);
  355.     printf("    Bits/Pixel:              %6d\n",bpp);
  356.     printf("    Angle of view:           %6d degrees\n",aov);
  357.     printf("    Aspect ratio:            %6.3f\n",(double)aspect);
  358.     printf("    Number of attributes:    %6d\n",natts);
  359.     printf("    Number of waves:         %6d\n",nwaves);
  360.     printf("\n");
  361.  
  362.     /* terminate the input file */
  363.     fclose(fp);
  364.     fp = NULL;
  365.     }
  366.  
  367.  
  368.